package tools

import (
	"encoding/json"
	"fmt"
	"os"
	"time"
)

//日志channel对象
var logChannel chan *LogModel

//日志channel大小
var logChannelSize int = 10000

//region 公开：初始化日志操作对象实例
func NewLogHelper(logpath string, logasync bool, sysname string) LogHelper {
	var objLogHelper LogHelper
	objLogHelper.SysName = sysname
	objLogHelper.LogAsync = logasync
	objLogHelper.LogPath = logpath
	if logasync {
		go func() {
			//消费搜索明细日志chan
			objLogHelper.consumeLogChannel()
		}()
	}

	return objLogHelper
}

//endregion

//region 公开：实体定义
type LogHelper struct {
	LogPath  string //日志文件存储目录
	LogAsync bool   //true为chan异步记录；false为同步记录文件；
	SysName  string //所属业务系统名称
}

type LogModel struct {
	SysName   string
	Message   string
	LogLevel  int32
	Exception error
	LogTime   time.Time
}

//endregion

//region 公开：记录日志方法入口
func (this *LogHelper) LogInfo(logstr string) {
	objLog := new(LogModel)
	objLog.LogLevel = 1
	objLog.Message = logstr
	objLog.SysName = this.SysName
	this.logBase(objLog)
}
func (this *LogHelper) LogError(logstr string, err error) {
	objLog := new(LogModel)
	objLog.LogLevel = 4
	objLog.Message = logstr
	objLog.SysName = this.SysName
	objLog.Exception = err
	this.logBase(objLog)
}

//endregion

//region 私有：记录日志基类方法，封装公共逻辑
func (this *LogHelper) logBase(objLog *LogModel) {
	objLog.LogTime = time.Now()
	if this.LogAsync {
		//异步记录日志
		this.addLogChannel(objLog)
	} else {
		//同步记录日志
		this.writeFileLog(objLog)
	}
}

//endregion

//region 私有：日志channel生产入口
func (this *LogHelper) addLogChannel(objLog *LogModel) {
	if logChannel == nil {
		logChannel = make(chan *LogModel, logChannelSize)
	}
	if len(logChannel) < logChannelSize {
		logChannel <- objLog
	}
}

//endregion

//region 私有：日志channel消费入口
func (this *LogHelper) consumeLogChannel() {
	if logChannel == nil {
		logChannel = make(chan *LogModel, logChannelSize)
	}
	for {
		if log, ok := <-logChannel; ok {
			this.writeFileLog(log)
			continue
		}
		time.Sleep(5 * time.Second)
	}
}

//endregion

//region 私有：记录文本日志
func (this *LogHelper) writeFileLog(objLog interface{}) {
	filename := this.getLogFileName()
	objfile, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		objfile, err = os.Create(filename)
	}
	defer objfile.Close()
	logmsg, err := json.Marshal(objLog)
	if err != nil {
		objfile.WriteString("记录文本日志异常：反序列化日志对象失败：" + err.Error())
		return
	}
	logmsg = append(logmsg, 10)
	objfile.Write(logmsg)
	objfile.WriteString("\r\n")

	fmt.Println(string(logmsg))
}

func (this *LogHelper) getLogFileName() string {
	filename := fmt.Sprintf(this.LogPath, time.Now().Format("2006-01-02"))
	_, err := os.Stat(this.LogPath)
	if err != nil {
		os.MkdirAll(this.LogPath, 0777)
	}
	return filename
}

//endregion
